package com.duojuhe.common.ueditor.main;


import com.duojuhe.common.bean.UserTokenInfoVo;
import com.duojuhe.common.constant.SingleStringConstant;
import com.duojuhe.common.file.service.FileUploadHandler;
import com.duojuhe.common.ueditor.constant.UEditorConstant;
import com.duojuhe.common.ueditor.dto.UploadState;
import com.duojuhe.common.ueditor.util.FileUtil;
import com.duojuhe.common.ueditor.util.JsonUtil;
import com.duojuhe.common.ueditor.util.ResponseUtil;
import com.duojuhe.common.config.FileUploadConfig;
import com.duojuhe.common.utils.file.UploadFileBean;
import com.duojuhe.common.utils.file.UploadFileUtil;
import com.duojuhe.coremodule.BaseService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.util.*;

/**
 * ueditor默认处理器
 *
 * @author
 * @date 2018/5/9
 */
@Slf4j
@Component
public class DefaultAction extends BaseService implements Action {
    @Resource
    private FileUploadConfig fileUploadConfig;
    @Resource
    private FileUploadHandler fileUploadHandler;
    /**
     * 上传图片
     */
    @Override
    public String uploadImage(MultipartFile upfile, HttpServletResponse response, HttpServletRequest request) {
        // 判断文件是否存在
        if (upfile == null) {
            return ResponseUtil.error(UEditorConstant.NOT_FOUND_UPLOAD_DATA);
        }
        //允许图片文件类型
        String[] allowFiles = fileUploadConfig.getImageAllowFiles();
        // 检查文件类型
        if (!fileTypeIsConformed(upfile, allowFiles)) {
            return ResponseUtil.error(UEditorConstant.NOT_ALLOW_FILE_TYPE);
        }
        long maxImageSize = fileUploadConfig.getMaxSize(fileUploadConfig.getMaxImageSize());
        // 检验图片大小
        if (upfile.getSize() > maxImageSize) {
            return ResponseUtil.error(UEditorConstant.MAX_SIZE);
        }
        //附件上传前缀域名
        String filePrefixDomain = fileUploadConfig.getFilePrefixDomain();
        //当前用户
        UserTokenInfoVo userTokenInfoVo = getCurrentLoginUserInfoDTO();
        //用户目录
        String userDir = userTokenInfoVo.getTenantNumber()+File.separator+userTokenInfoVo.getUserNumber();
        //用户聊天目录dir
        String imagesDir = File.separator+"images"+File.separator+userDir;
        //文件根目录
        String rootPath = fileUploadConfig.getRootPath()+imagesDir;
        //保存图片
        String fileUrlPrefix = fileUploadConfig.getFileUrlPrefix()+imagesDir;
        // 保存图片
        UploadFileBean uploadFileBean = UploadFileUtil.writeSingleImageToDisk(upfile,allowFiles,filePrefixDomain,rootPath, fileUrlPrefix);
        //请求路径
        String fileAbsolutePath = uploadFileBean.getFileAbsolutePath();
        if (StringUtils.isBlank(fileAbsolutePath)) {
            return ResponseUtil.error(UEditorConstant.IO_ERROR);
        }
        //保存文件到文件库
        fileUploadHandler.addNewFileUpload(uploadFileBean,userTokenInfoVo);
        //文件名称
        String originalFileName = upfile.getOriginalFilename();
        return JsonUtil.toJsonString(new UploadState(UEditorConstant.SUCCESS, fileAbsolutePath, originalFileName, originalFileName));
    }


    /**
     * 上传涂鸦
     *
     * @param base64
     * @param request
     * @return
     */
    @Override
    public String uploadScrawl(String base64, HttpServletRequest request) {
        // 判断文件是否存在
        if (StringUtils.isBlank(base64)) {
            return ResponseUtil.error(UEditorConstant.NOT_FOUND_UPLOAD_DATA);
        }
        //当前用户
        UserTokenInfoVo userTokenInfoVo = getCurrentLoginUserInfoDTO();
        //用户目录
        String userDir = userTokenInfoVo.getTenantNumber()+File.separator+userTokenInfoVo.getUserNumber();
        //用户涂鸦目录dir
        String scrawlDir = File.separator+"scrawl"+File.separator+userDir;
        //文件前缀
        String fileUrlPrefix = fileUploadConfig.getFileUrlPrefix()+scrawlDir;
        //文件根目录
        String rootPath = fileUploadConfig.getRootPath()+scrawlDir;
        // 保存涂鸦
        String url = FileUtil.writeImageBase64ToFile(base64,rootPath,fileUrlPrefix);
        if (url == null) {
            return ResponseUtil.error(UEditorConstant.IO_ERROR);
        }
        return JsonUtil.toJsonString(new UploadState(UEditorConstant.SUCCESS, url, "", ""));
    }

    /**
     * 上传视频
     */
    @Override
    public String uploadVideo(MultipartFile upfile, HttpServletRequest request) {
        // 判断文件是否存在
        if (upfile == null) {
            return ResponseUtil.error(UEditorConstant.NOT_FOUND_UPLOAD_DATA);
        }
        // 检查文件类型
        if (!fileTypeIsConformed(upfile, fileUploadConfig.getVideoAllowFiles())) {
            return ResponseUtil.error(UEditorConstant.NOT_ALLOW_FILE_TYPE);
        }
        // 检验视频大小
        if (upfile.getSize() > fileUploadConfig.getMaxSize(fileUploadConfig.getVideoMaxSize())) {
            return ResponseUtil.error(UEditorConstant.MAX_SIZE);
        }
        //当前用户
        UserTokenInfoVo userTokenInfoVo = getCurrentLoginUserInfoDTO();
        //用户目录
        String userDir = userTokenInfoVo.getTenantNumber()+File.separator+userTokenInfoVo.getUserNumber();
        //用户聊天目录dir
        String videoDir = File.separator+"video"+File.separator+userDir;
        //文件前缀
        String fileUrlPrefix = fileUploadConfig.getFileUrlPrefix()+videoDir;
        //文件根目录
        String rootPath = fileUploadConfig.getRootPath()+videoDir;
        // 保存视频
        String url = FileUtil.saveFile(upfile, rootPath,fileUrlPrefix);
        if (url == null) {
            return ResponseUtil.error(UEditorConstant.IO_ERROR);
        }
        String originalFileName = upfile.getOriginalFilename();
        return JsonUtil.toJsonString(new UploadState(UEditorConstant.SUCCESS, url, originalFileName, originalFileName));
    }

    /**
     * 上传附件
     */
    @Override
    public String uploadFile(MultipartFile upfile, HttpServletRequest request) {
        // 判断文件是否存在
        if (upfile == null) {
            return ResponseUtil.error(UEditorConstant.NOT_FOUND_UPLOAD_DATA);
        }
        // 检查文件类型
        if (!fileTypeIsConformed(upfile, fileUploadConfig.getFileAllowFiles())) {
            return ResponseUtil.error(UEditorConstant.NOT_ALLOW_FILE_TYPE);
        }
        long maxFileSize = fileUploadConfig.getMaxSize(fileUploadConfig.getMaxFileSize());
        // 检验文件大小
        if (upfile.getSize() > maxFileSize) {
            return ResponseUtil.error(UEditorConstant.MAX_SIZE);
        }
        //当前用户
        UserTokenInfoVo userTokenInfoVo = getCurrentLoginUserInfoDTO();
        //用户目录
        String userDir = userTokenInfoVo.getTenantNumber()+File.separator+userTokenInfoVo.getUserNumber();
        //用户聊天目录dir
        String fileDir = File.separator+"files"+File.separator+userDir;
        //文件根目录
        String rootPath = fileUploadConfig.getRootPath()+fileDir;
        //文件前缀
        String fileUrlPrefix = fileUploadConfig.getFileUrlPrefix()+fileDir;
        //附件上传前缀域名
        String filePrefixDomain = fileUploadConfig.getFilePrefixDomain();
        //允许文件类型
        String[] allowFiles = fileUploadConfig.getFileAllowFiles();
        //开始上传
        UploadFileBean uploadFileBean = UploadFileUtil.writeSingleFileToDisk(upfile,allowFiles,filePrefixDomain,rootPath, fileUrlPrefix);
        //请求路径
        String fileUrl = uploadFileBean.getFileAbsolutePath();
        if (StringUtils.isBlank(fileUrl)) {
            return ResponseUtil.error(UEditorConstant.IO_ERROR);
        }
        //保存文件到文件库
        fileUploadHandler.addNewFileUpload(uploadFileBean,userTokenInfoVo);
        //文件名称
        String originalFileName = upfile.getOriginalFilename();
        return JsonUtil.toJsonString(new UploadState(UEditorConstant.SUCCESS, fileUrl, originalFileName, originalFileName));
    }

    /**
     * 这里不支持远程抓图，关闭此功能。这个功能有安全风险
     *
     * @return
     */
    @Override
    public String catchImage(List<String> source) {
        return null;
    }


    /**
     * 获取最后的目录
     * @param path
     * @return
     */
    private static String getLastPath(String path){
        if(StringUtils.isBlank(path)){
           return StringUtils.EMPTY;
        }
        int index = path.lastIndexOf(File.separator);
        //然后取得最后的从索引1到字符串的最后的字符
        return path.substring(index);
    }
    /**
     * 显示文件目录
     * @param dir
     * @param list
     * @param fileUrlPrefix
     */
    private static void showDir(File dir ,List<Map<String, String>> list,String fileUrlPrefix,List<String> managerAllowFiles) {
        //抽象路径名数组，这些路径名表示此抽象路径名表示的目录中的文件和目录。
        File[] files = dir.listFiles();
        if(null!=files){
            for (File file : files) {
                if (file.isDirectory()) {
                    showDir(file,list,fileUrlPrefix,managerAllowFiles);
                } else {
                    String aftername = file.getPath().substring(file.getPath().lastIndexOf(SingleStringConstant.SPOT));
                    if(managerAllowFiles.contains(aftername)){
                        String url = fileUrlPrefix+getLastPath(file.getParent())+File.separator+file.getName();
                        Map<String, String> map = new HashMap<String, String>();
                        map.put("url",url);
                        list.add(map);
                    }
                }
            }
        }
    }

    @Override
    public String listImage(Integer start, Integer size) {
        Map<String, Object> result = new HashMap<String, Object>();
        try {
            String fileAbsolutePath = fileUploadConfig.getFilePrefixDomain();
            if (StringUtils.isBlank(fileAbsolutePath)) {
                HttpServletRequest request = ((ServletRequestAttributes) Objects.requireNonNull(RequestContextHolder.getRequestAttributes())).getRequest();
                fileAbsolutePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort();
            }
            List<Map<String, String>> imgList = new ArrayList<Map<String, String>>();
            //String path = fileUploadConfig.getRootPath();
            //当前用户
            UserTokenInfoVo userTokenInfoVo = getCurrentLoginUserInfoDTO();
            //用户目录
            String userDir = userTokenInfoVo.getTenantNumber()+File.separator+userTokenInfoVo.getUserNumber();
            //用户聊天目录dir
            String imagesDir = File.separator+"images"+File.separator+userDir;
            //文件根目录
            String path = fileUploadConfig.getRootPath()+imagesDir;

            String imageUrlPrefix = fileUploadConfig.getFileUrlPrefix();
            String fileUrl = fileAbsolutePath+imageUrlPrefix +imagesDir;
            File dir = new File(path);
            List<String> managerAllowFiles = Arrays.asList(fileUploadConfig.getImageAllowFiles());
            if(dir.exists()){
                showDir(dir,imgList,fileUrl,managerAllowFiles);
            }
            result.put("state", "SUCCESS");
            result.put("list", imgList); //图片路径列表
            result.put("size", size); //图片路径列表
            result.put("start", start); //图片开始位置
            result.put("total", imgList.size()); //图片总数
        } catch (Exception e) {
            result.put("state", "FAILED");
        }
        return JsonUtil.toJsonString(result);
    }

    @Override
    public String listFile(Integer start, Integer size) {
        Map<String, Object> result = new HashMap<String, Object>();
        try {
            String fileAbsolutePath = fileUploadConfig.getFilePrefixDomain();
            if (StringUtils.isBlank(fileAbsolutePath)) {
                HttpServletRequest request = ((ServletRequestAttributes) Objects.requireNonNull(RequestContextHolder.getRequestAttributes())).getRequest();
                fileAbsolutePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort();
            }
            List<Map<String, String>> fileList = new ArrayList<Map<String, String>>();
            //String path = fileUploadConfig.getRootPath();
            //当前用户
            UserTokenInfoVo userTokenInfoVo = getCurrentLoginUserInfoDTO();
            //用户目录
            String userDir = userTokenInfoVo.getTenantNumber()+File.separator+userTokenInfoVo.getUserNumber();
            //用户附件目录dir
            String filesDir = File.separator+"files"+File.separator+userDir;
            //文件根目录
            String path = fileUploadConfig.getRootPath()+filesDir;

            String fileUrlPrefix = fileUploadConfig.getFileUrlPrefix();
            String fileUrl = fileAbsolutePath+fileUrlPrefix +filesDir;
            File dir = new File(path);
            List<String> managerAllowFiles = Arrays.asList(fileUploadConfig.getFileAllowFiles());
            if(dir.exists()){
                showDir(dir,fileList,fileUrl,managerAllowFiles);
            }
            result.put("state", "SUCCESS");
            result.put("list", fileList); //文件路径列表
            result.put("size", size); //文件路径列表
            result.put("start", start); //文件开始位置
            result.put("total", fileList.size()); //文件总数
        } catch (Exception e) {
            result.put("state", "FAILED");
        }
        return JsonUtil.toJsonString(result);
    }


    /**
     * 检查文件类型
     */
    private boolean fileTypeIsConformed(MultipartFile upfile, String[] allowFiles) {
        if (upfile==null || StringUtils.isBlank(upfile.getOriginalFilename())){
            return false;
        }
        String suffix = FileUtil.getSuffixByFilename(upfile.getOriginalFilename());
        // 检验格式是否正确
        return Arrays.asList(allowFiles).contains(suffix);
    }

}
